<template>
  <div id="history-track-map" class="map">
    <div class="title-div">
      <span class="title">历史轨迹图</span>
    </div>
    <div class="map-search">
      <el-input v-model="state.searchValue" placeholder="输入搜索内容" @keyup.enter.prevent="onkeyup" :suffix-icon="search"/>
    </div>
    <div class="map-bracelet-setting">
      <el-button type="primary" class="setting-phone" @click="callBack({type: 'phone'})">设置亲情号码</el-button>
      <el-button type="primary" class="setting-trajectory" style="display: none">历史轨迹</el-button>
      <el-button type="primary" class="setting-fence" @click="onFence">{{ state.fenceText }}</el-button>
      <el-button type="primary" class="setting-fence" v-if="state.fenceDisplay" @click="clearFence">清除电子围栏</el-button>
    </div>

    <DynamicDialog ref="dynamicDialogRef" @click="callBack" :dialogVisible="state.dialogVisible"
                   title="设置亲情号码" :button="{cancel:false,confirm:false}">
      <template #dialog>
        <DynamicForm ref="dynamicFormRef" v-if="state.dialogVisible" @click="callBack" :rulesForm="state.rulesForm"
                     :rules="state.rules" width="500px"/>
      </template>
    </DynamicDialog>
  </div>
</template>

<script setup lang="ts">

import {onMounted, defineProps, reactive, nextTick, ref, watch} from 'vue';
import {Search} from '@element-plus/icons-vue'
import {loadAmap, options, autoOptions} from '@/utils/aMap';
import AMapLoader from '@amap/amap-jsapi-loader';
import {shallowRef} from '@vue/reactivity'
import {ElMessage} from "element-plus";

import DynamicForm from '@/components/layout/form/dynamic-form.vue'
import DynamicDialog from '@/components/layout/dialog/dynamic-dialog.vue'

const dynamicFormRef = ref(DynamicForm)
const dynamicDialogRef = ref(DynamicDialog)

import {electronicFenceApi, findBraceletApi} from "@/api/lms";
import Storage from "@/utils/storage";
import {ACCESS_TOKEN_KEY} from "@/utils/enums/cache-enum";
import {setSosPhoneApi} from "@/api/iot";

const search = Search
let map = shallowRef(null);
const amapOptions = loadAmap
let mapAMap: any

const state = reactive({
  searchValue: '' as string,
  marker: null as any,
  fence: false,
  fenceDisplay: false,
  fenceText: '设置电子围栏',
  polyEditor: null as any,
  device: null as any,
  deviceCode: '',
  dialogVisible: false,
  rulesForm: [{
    label: null, card: [
      {
        label: '亲情号码1',
        name: 'phone0',
        type: 'text',
        span: 24
      },
      {
        label: '亲情号码2',
        name: 'phone1',
        type: 'text',
        span: 24
      },
      {
        label: '亲情号码3',
        name: 'phone2',
        type: 'text',
        span: 24
      },
    ]
  }],
  rules: {
    phone0: [{required: true, message: '亲情号码1必填', trigger: 'blur'},
      {min: 7, max: 13, message: '亲情号码必须为 7 - 13', trigger: 'blur'}]
  }
})

const props = defineProps({
  deviceCode: null as any,
})

onMounted(() => {
  init();
  nextTick(() => {
    state.deviceCode = props.deviceCode
    findBracelet(state.deviceCode);
  })
});

const callBack = (data: any) => {
  switch (data.type || '') {
    case 'dialogClose':
      state.dialogVisible = false
      break
    case 'submit':
      // eslint-disable-next-line no-case-declarations
      let phones = [] as any
      // eslint-disable-next-line no-case-declarations
      let phoneList = [] as any
      for (let i in data.data) {
        phones.push(data.data[i])
        phoneList.push({name: '亲情号码' + i, cellphone: data.data[i]})
      }
      setSosPhone(phones)
      setPhone(phoneList)
      state.dialogVisible = false
      break
    case 'phone':
      state.dialogVisible = true
      break
    default:
      break
  }
}

const onFence = () => {
  state.fence = !state.fence
  if (state.fence) {
    state.fenceText = '保存电子围栏'
    state.fenceDisplay = true
    if (state.polyEditor) {
      state.polyEditor.open()
    } else {
      let positions = triangle();
      polyEditor(positions, true)
    }
  } else {
    if (state.polyEditor) {
      // 获取到全部经纬度
      let pathList = state.polyEditor.getTarget()._opts.path
      if (pathList) {
        let fence: { longitude: any; latitude: any; }[] = []
        pathList.forEach((e: any) => {
          fence.push({longitude: e[0], latitude: e[1]})
        })
        electronicFence(fence)
      }
      state.polyEditor.close()
    }
    state.fenceDisplay = false
    state.fenceText = '设置电子围栏'
  }
}
const triangle = () => {
  let position;
  try {
    position = map.getCenter()
  } catch (e) {
    position = {lng: options.center[0], lat: options.center[1]}
  }
  let positions = []
  const {lng, lat} = position
  if (positions.length == 0) {
    positions.push([lng, lat])

    let r = 6371000.79;
    let radius = 100
    let numpoints = 360;
    let phase = 2 * Math.PI / numpoints;

    //画图
    for (let i = 0; i < 2; i++) {
      /**
       * 计算坐标点
       */
      let dx = (radius * Math.cos((i * 30) * phase));
      let dy = (radius * Math.sin((i * 30) * phase));//乘以1.6 椭圆比例

      /**
       * 转换成经纬度
       */
      let dlng = dx / (r * Math.cos(lat * Math.PI / 180) * Math.PI / 180);
      let dlat = dy / (r * Math.PI / 180);
      positions.push([lng + dlng, lat + dlat])
    }
  }
  return positions;
}

const clearFence = () => {
  electronicFence([])
  let polygon = map.getAllOverlays('polygon')
  map.remove(polygon)
  state.polyEditor.close()
  state.polyEditor = null
  state.fenceDisplay = false
  state.fence = !state.fence
  state.fenceText = '设置电子围栏'
}

const polyEditor = (positions = [] as any, isOpen = false) => {
  if (positions.length === 0) {
    return
  }
  const polygon = new mapAMap.Polygon({
    path: positions,
    strokeColor: "#d9ecff",
    strokeWeight: 6,
    strokeOpacity: 0.2,
    fillOpacity: 0.4,
    fillColor: '#1791fc',
    zIndex: 50,
  })
  let polyEditor = null as any;
  try {
    map.add(polygon)
    // 缩放地图到合适的视野级别
    map.setFitView([polygon])

    polyEditor = new mapAMap.PolyEditor(map, polygon)
    state.polyEditor = polyEditor
  } catch (e) {
    console.log('polyEditor', e)
  }
  if (!polyEditor) {
    return;
  }
  if (isOpen) {
    state.polyEditor.open()
  }
}

/**
 * 初始化函数
 **/
const init = async () => {
  AMapLoader.load(amapOptions).then((AMap) => {
    mapAMap = AMap
    //设置地图容器id
    map = new AMap.Map("history-track-map", {  //设置地图容器id
      viewMode: options.viewMode,    //是否为3D地图模式
      zoom: options.zoom,           //初始化地图级别
      center: options.center, //初始化地图中心点位置
    });
    geolocation(AMap)
  }).catch(e => {
    console.log('AMap', e);
  })
};
// 创建一个 Marker 实例：
const addMarker = (lng: number, lat: number) => {
  if (state.marker) {
    state.marker.setPosition(new mapAMap.LngLat(lng, lat))
    map.setCenter([lng, lat])
  }
  let position = (!lat || !lng) ? map.getCenter() : new mapAMap.LngLat(lng, lat)
  state.marker = new mapAMap.Marker({
    position: position,
    offset: new mapAMap.Pixel(-13, -30),
    // 设置是否可以拖拽
    draggable: true,
    cursor: 'move',
    // 设置拖拽效果
    raiseOnDrag: true,
  });
  // 覆盖物拖拽事件
  state.marker.on('dragend', (e: any) => {
    if (e) {
      const {lng, lat} = e.lnglat
      map.setCenter([lng, lat])
    }
  });
  // 将创建的点标记添加到已有的地图实例：
  map.add(state.marker);
}
/**
 * 创建窗体
 * @param AMap 地图
 */
const autocomplete = (keyword: any) => {
  if (!keyword) {
    return
  }
  mapAMap.plugin('AMap.Autocomplete', () => {
    debugger
    let autoComplete = new mapAMap.Autocomplete(autoOptions);
    autoComplete.search(keyword, (status: any, result: any) => {
      if (status === 'complete' && result.info === 'OK') {
        const tips = result.tips[0]
        const {lng, lat} = tips.location
        addMarker(lng, lat)
      } else {
        ElMessage.warning('未搜索到该地名！')
      }
      console.log('autoComplete', {status, result})
    })
  })
}

/**
 * 搜索
 * @param event 控件
 */
const onkeyup = (event) => {
  autocomplete(state.searchValue)
}

/**
 * 初始化定位
 * @param AMap 地图
 */
const geolocation = (AMap: any) => {
  AMap.plugin('AMap.Geolocation', function () {
    const geolocation = new AMap.Geolocation({
      // 是否使用高精度定位，默认：true
      enableHighAccuracy: true,
      // 设置定位超时时间，默认：无穷大
      timeout: 10000,
      // 定位按钮的停靠位置的偏移量
      offset: [10, 20],
      //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
      zoomToAccuracy: true,
      //  定位按钮的排放位置,  RB表示右下
      position: 'RB'
    })

    geolocation.getCurrentPosition((status: string, result: any) => {
          if (status == 'complete' && result.info === 'SUCCESS') {
            const {lng, lat} = result.location
            addMarker(lng, lat)
          } else {
            addMarker()
          }
        }
    )
  })
}
const setSosPhone = (phone = [] as any) => {
  let deviceCode = state.deviceCode ? state.deviceCode : state.device.deviceCode
  let data = {deviceCode: deviceCode, phoneList: phone}

  setSosPhoneApi(data).then(res => {
    if (res.code === 0) {
      ElMessage.success('保存成功！')
    } else {
      ElMessage.warning('保存失败！')
      console.log('error', res)
    }
  })
}
const setPhone = (phone = [] as any) => {
  let data;
  if (state.device) {
    data = state.device
    data['emergency'] = phone
  } else {
    data = {deviceCode: state.deviceCode, emergency: phone}
  }
  electronicFenceApi(data).then(res => {
    if (res.code === 0) {
      ElMessage.success('保存成功！')
    } else {
      ElMessage.warning('保存失败！')
      console.log('error', res)
    }
  })
}
const electronicFence = (fence = [] as any) => {
  if (fence.length == 0) {
    state.device.positionList = []
  }
  let data;
  if (state.device) {
    data = state.device
    data['positionList'] = fence
  } else {
    data = {deviceCode: state.deviceCode, positionList: fence}
  }
  electronicFenceApi(data).then(res => {
    if (res.code === 0) {
      ElMessage.success('保存成功！')
    } else {
      ElMessage.warning('保存失败！')
      console.log('error', res)
    }
  })
}
const findBracelet = (deviceCode: string) => {
  findBraceletApi({deviceCode: deviceCode}).then((data: any) => {
    console.log('findBracelet', data)
    state.device = data
    const positionList = [] as any
    if (data && data.positionList) {
      data.positionList.forEach(({longitude = null as any, latitude = null as any}) => {
        if (longitude && latitude) {
          positionList.push([longitude, latitude])
        }
      })
    }
    if (data && data.emergency) {
      for (let i in data.emergency) {
        let phone = data.emergency[i]
        let label = 'phone' + i
        let item = state.rulesForm[0].card.find(({name = ''}) => name === label)
        if (item) {
          item[label] = phone.cellphone
        }
      }
    }
    polyEditor(positionList)
  })
}

</script>

<style lang="less" scoped>

.map {
  position: relative;
  border: 1px solid rgba(198, 202, 209, 0.5);
  border-radius: 8px;
  padding: 50px 20px 20px 20px;
  height: 500px;

  .map-search,
  .map-bracelet-setting {
    width: 200px;
    position: absolute;
    z-index: 999;
    right: 10px;
  }

  .map-search {
    top: 10px;
    right: 10px;
  }

  .map-bracelet-setting {
    top: 10px;
    left: 10px;
    display: flex;

    .el-button {
      flex: 1;
    }
  }

  .title-div {
    position: absolute;
    top: 10px;
    left: 20px;
    display: flex;

    .title {
      font-weight: bold;
      color: rgba(0, 0, 0, 0.6);
      margin-bottom: 10px;
    }
  }
}
</style>
